IAMユーザ本人にMFAを管理してもらうためのIAMポリシー
はじめに
こんにちは、虎塚です。
組織でAWSアカウントを利用する際には、担当者ごとにIAMユーザを払い出し、各ユーザが自分でMFA (Multi-Factor Authentication) を有効にすることが推奨されています。クラスメソッドでも、お客様の環境ごとにIAMユーザを作成し、MFAを設定していただくようにお願いしています。
ここで問題になるのが、IAMのポリシーです。IAMユーザ本人に自分自身のMFAを管理できるようにするには、どんなポリシーが適切なのでしょうか? このテーマは、当ブログの過去記事でも何度か登場していますね。
2015年8月現在、上記で紹介されたポリシーでは正常に動かなかったため、ここで改めてご紹介します。
結論
次のポリシーを適用することで、IAMユーザは自分自身のMFAを管理できます。
- 012345678901は、12桁のAWSアカウントIDに読み替えてください
- ${aws:username}は、APIを発行したIAMユーザのユーザ名を参照するための記述です(そのままでOK)
- 利用目的に合った権限を、別途IAMポリシーで与えているものとします
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "iam:ListUsers" ], "Resource": [ "arn:aws:iam::012345678901:user/" ] }, { "Effect": "Allow", "Action": [ "iam:ListVirtualMFADevices" ], "Resource": [ "arn:aws:iam::012345678901:mfa/" ] }, { "Effect": "Allow", "Action": [ "iam:EnableMFADevice", "iam:DeactivateMFADevice", "iam:ResyncMFADevice", "iam:ListMFADevices" ], "Resource": [ "arn:aws:iam::012345678901:user/${aws:username}" ] }, { "Effect": "Allow", "Action": [ "iam:DeleteVirtualMFADevice", "iam:CreateVirtualMFADevice" ], "Resource": [ "arn:aws:iam::012345678901:mfa/${aws:username}" ] } ] }
上記で用は足りるとおもいますが、IAMの話が好きな方は続きもお読みいただければ幸いです。
解説
前提: APIの種別
MFA関連のAPIには、ユーザを対象とするものと、MFAを対象とするものとがあります。実験をすれば詳細が分かりますが、IAMのAPIリファレンスを一瞥しただけでは、指定対象として適切なリソースを特定しづらいかもしれません。
また、さらにくわしく見ると、指定対象には「(アカウントに紐づく)すべてのIAMユーザ」と「IAMユーザ本人」、または「(アカウントに紐づく)すべてのMFA」と「IAMユーザ本人のMFA」の選択があります。
指定対象のリソースとIAMポリシーの記述方法を、次の表に示します。
指定対象リソース | IAMポリシーの記述 |
---|---|
すべてのIAMユーザ | arn:aws:iam::012345678901:user/ |
IAMユーザ本人 | arn:aws:iam::012345678901:user/${aws:username} |
すべてのMFA | arn:aws:iam::012345678901:mfa/ |
IAMユーザ本人のMFA | arn:aws:iam::012345678901:mfa/${aws:username} |
IAMユーザを対象とするAPI
次のAPIは、操作対象のリソースとしてIAMユーザ本人を指定します。
- ResyncMFADevice
- DeactivateMFADevice
- EnableMFADevice
上記のAPIは、すべてのIAMユーザをリソースに指定しても動作します。ただし、なにか意図がない限り、IAMユーザ本人を指定したほうがよいでしょう。特にDeactivateMFADeviceは、後述するDeleteVirtualMFADeviceの操作権限がなくても実行できるため、他のIAMユーザのMFAを削除できてしまいます。
次のAPIは、操作対象のリソースとしてIAMユーザ本人もしくは、すべてのIAMユーザを指定します。
- ListMFADevices
このAPIは、Management ConsoleのIAMユーザ詳細画面で、MFAの情報を表示するために必要です。IAMユーザ本人を指定すると、本人の情報だけが表示されます。すべてのIAMユーザを対象にすると、他のIAMユーザの詳細画面でもMFA情報が表示されます。
なお、MFAを有効化してからListMFADevicesの許可を削除してしまうと、「Management Console上ではMFAが関連づけられていないように見えるが、じつは関連づけられている」という最高の状態になってハマりますので、注意してください。「MFADevice entity at the same path and name already exists.」というエラーが表示されたら、その状況に陥っていないか確認してください。
MFAを対象とするAPI
次のAPIは、操作対象のリソースとしてIAMユーザ本人のMFAを指定します。
- CreateVirtualMFADevice
- DeleteVirtualMFADevice
これらをMFAに対して許可していないと、たとえEnableMFADevice/DeactiveMFADeviceをユーザに対して許可していても、MFAの有効化/無効化に失敗します。
上記のAPIは、すべてのMFAをリソースに指定しても動作します。MFAを有効化/無効化できるかどうかは、IAMユーザに対してEnableMFADevice/DeactivateMFADeviceの操作を許可しているかに依存するので、すべてのMFAをリソースに指定することのデメリットは特にないと思います。が、やはり特別な意図がない限り、本人に対してのみ許可しましょう。
次のAPIは、操作対象のリソースとしてすべてのMFAを指定します。
- ListVirtualMFADevices
IAMユーザ本人のMFAだけを指定すると、MFAの作成ができません(MFAの同期や削除はできます)。QRコードの画面にたどり着く前に、「User: arn:aws:iam::012345678901:user/iam-user-name is not authorized to perform: iam:ListVirtualMFADevices on resource: arn:aws:iam::012345678901:mfa/」というエラーになります。
推測ですが、MFAの作成時には、エンティティの重複が起きないように、内部的に既存のMFAをチェックする必要があるからではないかと思います。MFAの同期や削除は、本人のMFAのARNさえ取得できれば実行できそうです。
設定ミスによる様々なエラー
上記を守らなかった場合、様々なエラーに遭遇できます。
EnableMFADeviceが許可されていない場合は、QRコードが表示される画面で認証コードを入れた後、次へ進もうとすると「User: arn:aws:iam::012345678901:user/iam-user-name is not authorized to perform: iam:EnableMFADevice on resource: user iam-user-name」というエラーになります。エラーメッセージから、IAMユーザ本人をリソースに指定するべきだと分かります。
DeleteVirtualMFADeviceの許可はあるが、DeactiveMFADeviceの許可がないと、「User: arn:aws:iam::012345678901:user/iam-user-name is not authorized to perform: iam:DeactiveMFADevice on resource: user iam-user-name」というエラーになります。こちらも、エラーメッセージから、IAMユーザ本人をリソースに指定するべきだと分かります。
上のほうで述べたことの繰り返しになりますが、逆の場合、つまりDeactiveMFADeviceの許可はあるが、DeleteVirtualMFADeviceの許可がない場合は、MFAを無効化できてしまうので注意してください。
しかしながら、EnableMFADeviceの許可があっても、CreateVirtualMFADeviceとDeleteVirtualMFADeviceの許可がないと、MFAを有効化できません。「User: arn:aws:iam::012345678901:user/iam-user-name is not authorized to perform: iam:DeleteVirtualMFADevice on resource: arn:aws:iam::012345678901:mfa/iam-user-name」というエラーになります。エラーメッセージから、IAMユーザ本人のMFAをリソースに指定するべきだと分かります。
まとめ
解説した内容を次の表にまとめます。
API | 指定する対象リソース |
---|---|
ResyncMFADevice | IAMユーザ本人 |
DeactivateMFADevice | IAMユーザ本人(すべてのIAMユーザ指定はNG) |
EnableMFADevice | IAMユーザ本人 |
ListMFADevices | IAMユーザ本人(もしくは、すべてのIAMユーザでもよい) |
CreateVirtualMFADevice | IAMユーザ本人のMFA |
DeleteVirtualMFADevice | IAMユーザ本人のMFA |
ListVirtualMFADevices | すべてのMFA(IAMユーザ本人のMFA指定はNG) |
一見複雑ですが、エラーメッセージを確認すればどんな設定が不足しているか分かりますので、安心してください。
おわりに
MFAをムファッといい感じに設定して、アカウントのセキュリティを維持しましょう!
それでは、また。